package com.example.chinesenation.Interceptor;

import com.example.chinesenation.Exception.AuthenException;
import com.example.chinesenation.Response.ResultType;
import com.example.chinesenation.Utils.Audience;
import com.example.chinesenation.Utils.JwtTokenUtil;
import com.example.chinesenation.annotation.AuthenToken;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author sakuraFallingDown
 * @version 1.0
 * @date 2021/1/11 14:31
 */
@Configuration
public class MyInterceptor implements HandlerInterceptor {
    @Autowired
    private Audience audience;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws AuthenException{//JWT预处理
        HandlerMethod hm=null;
        if(handler instanceof HandlerMethod){//映射到具体函数
            hm=(HandlerMethod)handler;
        }else{//不是映射到具体函数，直接跳过
            return true;
        }
        //JWT认证
        String token=request.getHeader("token");
        Method method=hm.getMethod();
        if(method.isAnnotationPresent(AuthenToken.class)){//需要认证的才需要认证JWT
            //JWT认证
            if(token==null) throw new AuthenException(ResultType.TOKENEXPIRE);
            if(audience == null){
                BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
                audience = (Audience) factory.getBean("audience");
            }
            // 验证token是否有效--无效已做异常抛出，由全局异常处理后返回对应信息
            try {
                JwtTokenUtil.parseJWT(token, audience);
            }catch (AuthenException e){
                throw e;
            }
        }
        return true;
    }
}
